package whf.framework.resource.db;

import java.beans.PropertyDescriptor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.lang.StringUtils;

import whf.framework.log.Log;
import whf.framework.log.LogFactory;

/**
 * @author wanghaifeng
 * @version 1.0
 */
public class ConnectionManager {
	private static Log log = LogFactory.getLog(ConnectionManager.class);
	
	private static ConnectionManager defaultInstance;
	private boolean initialized;
	private BasicDataSource ds = null;

	public ConnectionManager(){
		this.init(null, null, null, null, null);
	}
	
	public ConnectionManager(String driver, String url, String username, String password, Map<String,String> props){
		this.init(driver, url, username, password, props);
	}
	/**
	 * 
	 */
	private synchronized void init(String driver, String url, String username, String password, Map<String,String> props){
		if( initialized ) return;
		try{
			Configuration configuration = new PropertiesConfiguration(ConnectionManager.class.getResource("config.properties"));
			if(props != null && !props.isEmpty()){
				for(String key: props.keySet()){
					String value = props.get(key);
					if(!StringUtils.isEmpty(value)){
						configuration.setProperty(key, value);
					}
				}
			}
			if(!StringUtils.isEmpty(driver) && !StringUtils.isEmpty(url) && !StringUtils.isEmpty(username)){
				configuration.setProperty("driverClassName", driver);
				configuration.setProperty("url", url);
				configuration.setProperty("username", username);
				configuration.setProperty("password", password);
			}
			//log data
			for(Iterator keys = configuration.getKeys(); keys.hasNext(); ){
				String key = (String)keys.next();
				String value = configuration.getString(key);
				log.debug(key + "\t=" + value);
			}
			//
			this.ds = new BasicDataSource();
			this.ds.setDriverClassName(configuration.getString("driverClassName"));
			this.ds.setUrl(configuration.getString("url"));
			this.ds.setUsername(configuration.getString("username"));
			this.ds.setPassword(configuration.getString("password"));
			String validationQuery = configuration.getString("validationQuery");
			if(!StringUtils.isEmpty(validationQuery)){
				this.ds.setValidationQuery(validationQuery);
			}
			for(Iterator keys = configuration.getKeys(); keys.hasNext(); ){
				String propertyName = (String)keys.next();
				PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(ds, propertyName);
				if(descriptor == null || descriptor.getWriteMethod() == null) continue;
				try{
					if(descriptor.getPropertyType() == int.class){
						PropertyUtils.setProperty(ds, propertyName, new Integer(configuration.getInt(propertyName)));
					} else if(descriptor.getPropertyType() == long.class){
						PropertyUtils.setProperty(ds, propertyName, new Long(configuration.getLong(propertyName)));
					}
				}catch(Exception e){
					log.debug(this, e);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		initialized = true;
	}
	
	protected void finalize() throws Throwable {
		super.finalize();
		if(ds!=null){
			ds.close();
		}
	}

	public Connection getPooledConnection(){
		try{
			Connection con = ds.getConnection();
			if(con == null){
				throw new Exception();
			}
			return con;
		}catch(Exception e){
			log.error(this, e);
			return null;
		}
	}
	
	/**
	 * @return ConnectionManager????
	 */
	public static ConnectionManager getDefaultInstance(){
		if(defaultInstance == null){
			defaultInstance = new ConnectionManager();
		}
		return defaultInstance;
	}
	
	/**
	 * @return
	 */
	public static Connection getConnection(){
		return getDefaultInstance().getPooledConnection();
	}
	
	public static void main(String args[]) throws Exception{
//		PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(BasicDataSource.class);
//		for(int i=0;i<descriptors.length; i++){
//			System.out.println(descriptors[i].getName()+"="+descriptors[i].getPropertyType());
//		}
		//
//		URL url = ConnectionManager.class.getClassLoader().getResource("dbconfig.properties");
//		System.out.println(url);
//		Configuration config = new PropertiesConfiguration(url);
//		Iterator it = config.getKeys();
//		while(it.hasNext()){
//			String key = (String)it.next();
//			System.out.println(config.getInt(key));
//		}
		//
		Connection con = ConnectionManager.getConnection();
		//String sql = "insert into qzj_jftzs(ZSDWBH,TZSBH) values(?,?)";
		String sql = "insert into qzj_qxjftzs values(?,?,?,?,?)";
		PreparedStatement pstmt = con.prepareStatement(sql);
		for(int i=0; i< 5000; i++){
			pstmt.setString(1, String.valueOf(i));
			pstmt.setString(2, String.valueOf(i));
			pstmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
			pstmt.setString(4, "0");
			pstmt.setString(5, "Reson"+i);
			pstmt.executeUpdate();
		}
		System.out.println(con);
		con.close();
	}
}
